#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
#include<stdlib.h>
#define N 3
#define CUSTOMERS 10
sem_t barber_ready;
sem_t customer_ready;
sem_t seat_mutex;
int waiting=0;
void* barber(void* arg){
	while(1){
		sem_wait(&customer_ready);
		sem_wait(&seat_mutex);
		waiting--;
		sem_post(&barber_ready);
		printf("[Barber] Cutting hair.Waiting:%d.\n",waiting);
		sem_post(&seat_mutex);
		sem_post(&barber_ready);
		sleep(rand()%3+1);
	}
	return NULL;
}
void* customer(void* arg){
	int id=*((int*)arg);
	sem_wait(&seat_mutex);
	if(waiting<N){
		waiting++;
		printf("[Customer%d]Sat down.Waiting:%d\n",id,waiting);
		sem_post(&customer_ready);
		sem_post(&seat_mutex);
		sem_wait(&barber_ready);
		printf("[Customer%d] Getting haircut\n",id);
		sleep(rand()%2+1);
	}else{
		sem_post(&seat_mutex);
		printf("[Customer%d] Left,no seats\n",id);
	}
	return NULL;
}
int main(){
	sem_init(&barber_ready,0,0);
	sem_init(&customer_ready,0,0);
	sem_init(&seat_mutex,0,1);
	pthread_t barber_thread;
	pthread_create(&barber_thread,NULL,barber,NULL);
	pthread_t customers[CUSTOMERS];
	int customer_ids[CUSTOMERS];
	for(int i=0;i<CUSTOMERS;i++)
	{
		customer_ids[i]=i+1;
		sleep(rand()%2);
		pthread_create(&customers[i],NULL,customer,&customer_ids[i]);
	}
	for(int i=0;i<CUSTOMERS;i++){
		pthread_join(customers[i],NULL);
	}

	return 0;
}
